package com.cxs.plan.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cxs.plan.VO.FilterUserVO;
import com.cxs.plan.VO.UserVO;
import com.cxs.plan.annotation.PagingQuery;
import com.cxs.plan.domain.LoginUser;
import com.cxs.plan.DTO.UserDTO;
import com.cxs.plan.domain.entity.User;
import com.cxs.plan.mapper.UserWithRoleMapper;
import com.cxs.plan.service.UserService;
import com.cxs.plan.mapper.UserMapper;
import com.cxs.plan.utils.BaseContext;
import com.cxs.plan.utils.JwtUtil;
import com.cxs.plan.utils.RedisCache;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author 11756
 * @description 针对表【user(用户信息)】的数据库操作Service实现
 * @createDate 2024-03-03 16:31:38
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    @Resource
    private JwtUtil jwtUtil;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserWithRoleMapper userWithRoleMapper;

    @Override
    public String loginUser(String username, String password) {
        Authentication authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        if (Objects.isNull(authenticate)) {
            throw new RuntimeException("用户名或密码错误");
        }
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        Integer userId = loginUser.getUser().getId();
        String jwt = jwtUtil.createJWT(String.valueOf(userId));
        //authenticate存入redis
        redisCache.setCacheObject("login:" + userId, loginUser);
        return jwt;
    }

    @Override
    @PagingQuery
    public List<User> getUserList() {
        return userMapper.getUserList();
    }

    @Override
    public void updateUser(UserDTO userDTO) {
        User user = userMapper.selectById(userDTO.getId());
        userDTO.setPassword(user.getPassword());
        BeanUtils.copyProperties(userDTO, user);
        userMapper.updateById(user);
        userWithRoleMapper.deleteByUserId(userDTO.getId());
        userWithRoleMapper.saveUserWithRole(userDTO.getId(), userDTO.getRoleIds());
    }

    @Transactional
    @Override
    public void saveUser(UserDTO userDTO) {
        if(userMapper.selectByUsername(userDTO.getUsername()) != null){
            throw new RuntimeException("用户名已存在");
        }
        if (userDTO.getRoleIds() == null || userDTO.getRoleIds().isEmpty()) {
            throw new RuntimeException("角色不能为空");
        }
        if (userDTO.getPassword() == null) {
            throw new RuntimeException("密码不能为空");
        }
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        user.setPassword(encoder.encode(user.getPassword()));
        userMapper.insert(user);
        userWithRoleMapper.saveUserWithRole(user.getId(), userDTO.getRoleIds());
    }

    @Override
    public UserDTO getUserById(Integer id) {
        User user = userMapper.selectById(id);
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);
        userDTO.setRoleIds(userWithRoleMapper.getRoleIdsByUserId(id));
        return userDTO;
    }

    @Transactional
    @Override
    public void delUserById(Integer id) {
        userMapper.deleteById(id);
        userWithRoleMapper.deleteByUserId(id);
    }

    @Override
    public UserVO getUserInfo() {
        Integer id = BaseContext.getCurrentId();
        if (id != null) {
            User user = userMapper.selectById(id);
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            return userVO;
        }
        return null;
    }

    @Override
    public List<FilterUserVO> selectUserListByName(String name) {
        if(name == null || name.isEmpty()){
            return new ArrayList<>();
        }
        return userMapper.selectListByName(name).stream().filter(i -> !i.getId().equals(BaseContext.getCurrentId())).collect(ArrayList::new, (list, item) -> {
            FilterUserVO vo = new FilterUserVO();
            BeanUtils.copyProperties(item, vo);
            list.add(vo);
        }, ArrayList::addAll);
    }
}




